home *** CD-ROM | disk | FTP | other *** search
- {**********************************************************************}
- { }
- { PROGRAM NAME: JLEM }
- { WRITTEN BY: JOHN NEMEC }
- { DATE: OCTOBER 1992 }
- { }
- { This PASCAL program reads an Intel hex file and sends data to the }
- { ROM EMULATOR in serial format. }
- { }
- { You can quit JLEM and unplug the emulator from the PC. The emulator }
- { will remain in the EMULATE mode and the target system will continue }
- { to run. }
- { }
- {**********************************************************************}
-
- program LEM;
-
-
- type hexstr = string[4];
-
- {**********************************************************************}
- { }
- { FUNCTION NCON }
- { }
- { Converts a string representing a hexadecimal number to the number }
- { }
- {**********************************************************************}
-
- function ncon(hexnum: hexstr): integer;
-
-
- {**********************************************************************}
- { }
- { FUNCTION NUMBER }
- { }
- { Converts an ASCII character representing a hex number into an integer}
- { }
- {**********************************************************************}
-
- function number(hexchr: char): integer;
- var temp: integer;
- begin
- hexchr := UpCase(hexchr);
- temp := Ord(hexchr) - 48;
- if (temp > 16) then begin
- temp := temp - 7;
- if (temp < 10) then temp := temp -10;
- end;
- if (temp > 15) then temp := -temp;
- number := temp;
- end;
-
- var i,t,sum,l: integer;
- begin
- l := length(hexnum);
- t := 1;
- sum := 0;
- for i := 1 to l do begin
- sum := sum + t*number(hexnum[l - i + 1]);
- t := t*16;
- end;
- ncon := sum;
- end;
-
- { }
- {**********************************************************************}
- { }
-
- type name = string[80];
- memarray = array[0..2047] of byte;
-
-
- {**********************************************************************}
- { }
- { PROCEDURE INTELREAD }
- { }
- { Reads the object code file in "INTEL HEX FORMAT", processes the }
- { data, does basic checks on the data, changes the instruction code }
- { from HEX to binary and stores it in the memory array. }
- { }
- {**********************************************************************}
-
- procedure intelread(intelname: name; var mdata: memarray; var maxadr: integer);
- var
- Buffer: char;
- intelfile: file of char;
- reclength: string[2];
- addresst: string[4];
- address, recint, i: integer;
-
- label start, error, stop, cont;
-
- { }
- {**********************************************************************}
- { }
- { OPEN THE FILE (USER ENTERS FILENAME) }
- { }
- {**********************************************************************}
- { }
-
- begin
- maxadr := 0;
- Assign(intelfile,intelname);
- Reset(intelfile);
- repeat
- start:
-
- { }
- {**********************************************************************}
- { }
- { READ RECORD MARK FIELD AND VERIFY CORRECT }
- { }
- {**********************************************************************}
- { }
-
- Read(intelfile,Buffer);
- if (Buffer = ':') then goto cont;
- for i := 1 to 3 do begin
- Read(intelfile,Buffer);
- if (Buffer = ':') then goto cont;
- end;
- writeln('no :');
- halt;
-
- { }
- {**********************************************************************}
- { }
- { READ RECORD LENGTH FIELD AND CONVERT TO INTEGER }
- { }
- {**********************************************************************}
- { }
-
- cont:
- reclength := '';
- Read(intelfile,Buffer);
- reclength := reclength + Buffer;
- Read(intelfile,Buffer);
- reclength := reclength + Buffer;
- recint := ncon(reclength);
- if (recint = 0) then goto stop;
-
- { }
- {**********************************************************************}
- { }
- { READ ADDRESS FIELD AND CONVERT TO INTEGER }
- { }
- {**********************************************************************}
- { }
-
- addresst := '';
- Read(intelfile,Buffer);
- addresst := addresst + Buffer;
- Read(intelfile,Buffer);
- addresst := addresst + Buffer;
- Read(intelfile,Buffer);
- addresst := addresst + Buffer;
- Read(intelfile,Buffer);
- addresst := addresst + Buffer;
- address := ncon(addresst);
-
-
- { }
- {**********************************************************************}
- { }
- { READ RECORD TYPE FIELD }
- { }
- {**********************************************************************}
- { }
-
- reclength := '';
- Read(intelfile,Buffer);
- reclength := reclength + Buffer;
- Read(intelfile,Buffer);
- reclength := reclength + Buffer;
- if (reclength <> '00') then goto stop;
-
-
- { }
- {**********************************************************************}
- { }
- { READ DATA FIELDS; REPEAT RECINT TIMES }
- { }
- {**********************************************************************}
- { }
-
- for i := 1 to recint do begin
- reclength := '';
- Read(intelfile,Buffer);
- reclength := reclength + Buffer;
- Read(intelfile,Buffer);
- reclength := reclength + Buffer;
- mdata[address + i -1] := ncon(reclength);
- if ((address + i - 1) > maxadr) then maxadr := address + i - 1;
- end;
-
- { }
- {**********************************************************************}
- { }
- { READ CHECKSUM FIELD }
- { }
- {**********************************************************************}
- { }
-
- reclength := '';
- Read(intelfile,Buffer);
- reclength := reclength + Buffer;
- Read(intelfile,Buffer);
- reclength := reclength + Buffer;
- until EOF(intelfile);
- stop:
- Close(intelfile);
- end;
-
- { }
- {**********************************************************************}
- { }
- { TIME DELAY PROCEDURE }
- { }
- {**********************************************************************}
- { }
-
- procedure tdly(n:integer);
- var i:integer;
- begin
- for i := 1 to n do;
- end;
-
-
- const td: integer = 10;
-
- procedure init;
-
- { }
- {**********************************************************************}
- { }
- { PUT THE SIMULATOR INTO THE LEARN MODE }
- { OUTPUT DATA TO PRINTER PORT 1 IN SERIAL MODE }
- { }
- {**********************************************************************}
- { }
-
- var
- i: integer;
-
- begin
- port[634] := $20;
- port[632] := 2; {DUMMY DATA TO PUT FLIP FLOP IN LEARN MODE}
- tdly(td);
- port[634] := $21;
- tdly(td);
- port[634] := $20;
- tdly(td);
- port[632] := 3;
- tdly(td);
- for i := 1 to 23 do begin
- port[634] := $21;
- tdly(td);
- port[634] := $20;
- tdly(td);
- end;
- port[632] := 0; {set control low -- CLOCK LEARN/EMULATE FLIP FLOP}
- tdly(td);
- port[634] := $21;
- tdly(td);
- port[634] := $20;
- tdly(td);
- port[632] := 2;
- end;
-
-
-
- procedure endload;
-
- { }
- {**********************************************************************}
- { }
- { PUT THE SIMULATOR IN THE EMULATE MODE }
- { USE DUMMY DATA; DON'T WRITE TO RAM BUT PUT 1 }
- { INTO FLIP FLOP TO PUT INTO EMULATE MODE }
- { }
- {**********************************************************************}
- { }
-
- var
- i: integer;
-
- begin
- port[632] := 3;
- tdly(td);
- for i := 1 to 24 do begin
- port[634] := $21;
- tdly(td);
- port[634] := $20;
- tdly(td);
- end;
- port[632] := 0; {set control low}
- tdly(td);
- port[634] := $21;
- tdly(td);
- port[634] := $20;
- tdly(td);
- port[632] := 2;
- end;
-
-
-
- { }
- {**********************************************************************}
- { }
- { PROCEDURE LOADBYTE }
- { Loads a byte of data into the memory at a specified address }
- { }
- {**********************************************************************}
- { }
-
-
- procedure loadbyte(data: byte; address: integer);
-
- var
- adrcont, i: integer;
- out: byte;
- begin
-
- { }
- {**********************************************************************}
- { }
- { Bit 0 of port [634] is clock (STROBE) }
- { Bit 0 of port [632] is data and bit 1 is control }
- { }
- {**********************************************************************}
- { }
-
- adrcont := address AND $0FFF;
- for i := 15 downto 0 do begin
- out := $02 OR ((adrcont SHR i) AND $01); {SERIALIZES INTEGER ADDRESS}
- port[632] := out;
- port[634] := $21;
- tdly(td);
- port[634] := $20;
- end;
- for i := 7 downto 0 do begin
- out := $02 OR ((data SHR i) AND $01); {SERIALIZES BYTE (INSTRUCTION)}
- port[632] := out;
- port[634] := $21;
- tdly(td);
- port[634] := $20;
- end;
- port[632] := 0; {SET CONTROL LOW}
- tdly(td);
- port[634] := $21; {STROBE INTO MEMORY}
- tdly(td);
- port[634] := $20;
- tdly(td);
- port[632] := 2;
- end;
-
-
-
- { }
- {**********************************************************************}
- { }
- { FUNCTION TEST }
- { Test to see if HEXNUM is valid hexadecimal number }
- { Lower case is assumed }
- { }
- {**********************************************************************}
- { }
-
- function test(hexnum: hexstr): boolean;
- var i: integer;
- temp,temp1: boolean;
- tempch: char;
-
- begin
- temp1 := TRUE;
- for i := 1 to length(hexnum) do begin
- tempch := UpCase(hexnum[i]);
- case tempch of
- '0': temp := TRUE;
- '1': temp := TRUE;
- '2': temp := TRUE;
- '3': temp := TRUE;
- '4': temp := TRUE;
- '5': temp := TRUE;
- '6': temp := TRUE;
- '7': temp := TRUE;
- '8': temp := TRUE;
- '9': temp := TRUE;
- 'A': temp := TRUE;
- 'B': temp := TRUE;
- 'C': temp := TRUE;
- 'D': temp := TRUE;
- 'E': temp := TRUE;
- 'F': temp := TRUE;
- else temp := FALSE;
- end;
- temp1 := temp1 AND temp;
- test := temp1;
- end;
- end;
-
-
- { }
- {**********************************************************************}
- { }
- { PROCEDURE HEXCHG }
- { Converts a number into the HEX representation as a string }
- { }
- {**********************************************************************}
- { }
-
- procedure hexchg(numin: integer; var hexnum: hexstr);
- {converts a number into the Hex representation as a string}
- var ch: string[1];
- temp,i: integer;
- begin
- hexnum := '';
- for i := 4 downto 1 do begin
- temp := (numin SHR (4*(i-1)) AND $000F);
- if (temp > 9) then temp := temp + 55 else temp := temp + 48;
- ch := Chr(temp);
- hexnum := hexnum + ch;
- end;
- end;
-
- { }
- {**********************************************************************}
- { }
- { MAIN PROGRAM BEGINS HERE }
- { }
- {**********************************************************************}
- { }
-
- var
- address, times, maxadr: integer;
- memory: memarray;
- cmd: char;
- hadr,prhex,memhex: hexstr;
- fname: name;
-
- label input1, input2, cycle1, cycle2, reread, reload, command;
-
- begin
- LowVideo;
- for address := 0 to 2047 do memory[address] := 0;
- write('Enter Intel hex code file name: ');
- readln(fname);
- if (Pos('.',fname) = 0) then fname := fname + '.hex';
- intelread(fname,memory,maxadr);
- reload:
- init;
- if (maxadr > 2047) then writeln('Warning program exceeds simulator memory.');
- writeln('Loading Simulator Module.');
-
- { }
- {**********************************************************************}
- { }
- { CALL "LOADBYTE" TO SEND BYTE AT A TIME WITH ADDRESS }
- { }
- {**********************************************************************}
- { }
-
- for address := 0 to maxadr do loadbyte(memory[address],address);
- endload; {PUT IN EMULATE MODE}
- writeln('Simulation mode.');
- command: writeln;
- read(KBD, cmd); {ACCEPT USER COMMAND}
- cmd := UpCase(cmd);
- case cmd of
- 'D': goto input2; {"D"ISPLAY MEMORY CONTENTS IN HEX ON SCREEN}
- 'C': goto input1; {"C"HANGE A BYTE}
- 'R': goto reload; {"R"ELOAD ENTIRE EMULATION RAM}
- 'Q': halt; {"Q"UIT -- RETURN TO DOS}
- else goto command;
- end;
-
- { }
- {**********************************************************************}
- { }
- { CHANGE MEMORY }
- { }
- {**********************************************************************}
- { }
-
- input1: write('C: ');
- readln(hadr);
- if (NOT test(hadr)) then goto input1;
- address := ncon(hadr);
- cycle1: hexchg(address, prhex);
- hexchg(memory[address], memhex);
- Delete(memhex, 1,2);
- write(prhex,': ',memhex,' ');
- reread:
- read(KBD, cmd);
-
- { }
- {**********************************************************************}
- { }
- { IF "SPACEBAR" IS PRESSED DON'T CHANGE; INCR ADDRESS }
- { }
- {**********************************************************************}
- { }
-
- if (cmd = '') then begin
- address := address + 1;
- writeln;
- goto cycle1;
- end;
- if (cmd = #13) then goto command;
- write(cmd);
-
- readln(memhex); {ENTER NEW BYTE TO BE PLACED AT ADDRESS}
- memhex := cmd + memhex;
- if ((NOT test(memhex)) OR (Length(memhex) > 2)) then goto reread;
- memory[address] := ncon(memhex);
- init; {PUT IN LEARN MODE}
- loadbyte(memory[address], address); {SEND ADDRESS & BYTE}
- endload; {PUT IN EMULATE MODE}
- hexchg(memory[address], memhex);
- Delete(memhex, 1,2);
- writeln(prhex,': ',memhex,' ');
- if (address < 2047) then address := address +1 else address :=0;
- goto cycle1;
- goto command;
-
-
-
- { }
- {**********************************************************************}
- { }
- { DISPLAY MEMORY }
- { Converts MEMARRAY into HEX so you can read it and puts it on the }
- { screen. }
- { }
- {**********************************************************************}
- { }
-
- input2: write('D: ');
- readln(hadr);
- if (NOT test(hadr)) then goto input2;
- address := ncon(hadr);
- times := 0;
- cycle2: times := times + 1;
- hexchg(address, prhex);
- hexchg(memory[address], memhex);
- Delete(memhex, 1,2);
- write(prhex,': ',memhex,' ');
- if ((address < 2046) AND (times < 128)) then begin
- address := address + 1;
- goto cycle2;
- end;
- writeln;
- goto command;
- end.
-